﻿using GalaSoft.MvvmLight;
using MoreEPG.Model;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Command;
using Wpf.DragDrop;
using System.Windows;
using System.Linq;
using MCHelp;
using Microsoft.MediaCenter.Guide;
using System.Collections.Generic;
using System;
using MoreEPG.Helper;
using GalaSoft.MvvmLight.Messaging;

namespace MoreEPG.ViewModel
{

    public class SortViewModel : ViewModelBase, IDropTarget
    {
        private bool ButtonCanExecute = false;
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        private MCConnection MCCon;
        private List<Channel> blockedChannels;
        private Core _Core = Core.Instance;

        /// <summary>
        /// Initializes a new instance of the SortViewModel class.
        /// </summary>
        public SortViewModel()
        {
            this.MCCon = _Core.MCCon;
            FillItems();
            this.InitCommands();
        }

        private void InitCommands()
        {
            this.Save = new RelayCommand(
                 () => OnSave(),
                 () => ButtonCanExecute);
        }

        private void OnSave()
        {
            int maxVisibleChannel = this.Items.Count + 1;
            List<Channel> ChannelsToUpdate = new List<Channel>();
            try
            {
                for (int y = 0; y < this.blockedChannels.Count; y++)
                {
                    Channel chan = this.blockedChannels.ElementAt(y);
                    chan.Number = maxVisibleChannel + y;
                    ChannelsToUpdate.Add(chan);
                }

                for (int i = 0; i < this.Items.Count; i++)
                {
                    GuideChannelInfo info = this.Items.ElementAt(i);
                    info.ChannelNum = i + 1;
                    info.channel.Number = i + 1;
                    ChannelsToUpdate.Add(info.channel);
                }
                if (ChannelsToUpdate.Count > 0)
                {
                    if (!this.MCCon.SaveChannels(ChannelsToUpdate))
                    {
                        var errmessage = new CustomDialogMessage(this.MCCon.lastError, CustomMessageBoxImage.Error, CustomMessageBoxButton.OK, null);
                        Messenger.Default.Send(errmessage);
                        return;
                    }
                }
                var message = new CustomDialogMessage("Fertig", CustomMessageBoxImage.Information, CustomMessageBoxButton.OK, null);
                Messenger.Default.Send(message);
                this.ButtonCanExecute = false;
                this.Save.RaiseCanExecuteChanged();
            }
            catch (Exception ex)
            {
                logger.ErrorException("Error Save Channels", ex);
                var message = new CustomDialogMessage(ex.Message, CustomMessageBoxImage.Error, CustomMessageBoxButton.OK, null);
                Messenger.Default.Send(message);
            }
        }
        


        public const string ItemsPropertyName = "Items";
        private ObservableCollection<GuideChannelInfo> _Items = new ObservableCollection<GuideChannelInfo>();
                
        public ObservableCollection<GuideChannelInfo> Items
        {
            get
            {
                return _Items;
            }

            set
            {
                if (_Items == value)
                {
                    return;
                }

                _Items = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(ItemsPropertyName);

               
            }
        }

        private void FillItems()
        {
            if (this.MCCon == null)
            {
                #region Dummy Datas
                for (int i = 0; i < 15; i++)
                {
                    GuideChannelInfo item = new GuideChannelInfo();
                    item.ChannelNum = i;
                    item.Name = "Channel0" + i.ToString();
                    item.ServiceInfo = "Service0" + i.ToString();
                    item.Id = i;
                    this._Items.Add(item);
                }
                #endregion
                return;
            }
            this.blockedChannels = this.MCCon.GetBlockedChannels().OrderBy(s => s.ChannelNumber.Number).ToList();
            Channel[] chans = this.MCCon.GetAllChannels(false).OrderBy(s => s.ChannelNumber.Number).ToArray();

            foreach (var channel in chans)
            {
                GuideChannelInfo item = new GuideChannelInfo();
                item.Name = channel.CallSign;
                item.Id = channel.Id;
                item.ChannelNum = channel.Number;
                item.ServiceInfo = channel.Service.Name;
                item.service = channel.Service;
                item.channel = channel;
                this._Items.Add(item);
            }
        }

        public RelayCommand Save
        {
            get;
            private set;
        }




        public void DragOver(DropInfo dropInfo)
        {
            dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
            dropInfo.Effects = DragDropEffects.Move;
        }

        public void Drop(DropInfo dropInfo)
        {
            var target = (GuideChannelInfo)dropInfo.TargetItem;
            var data = (GuideChannelInfo)dropInfo.Data;
            if (target == data)
            {
                return;
            }
            int insertIndex = dropInfo.InsertIndex;
            
            if (dropInfo.DragInfo.VisualSource == dropInfo.VisualTarget)
            {

                int index = this._Items.IndexOf(data);
                
                if (index != -1)
                {
                    this._Items.RemoveAt(index);

                    if ( index < insertIndex)
                    {
                        --insertIndex;
                    }
                }
                
            }
            this._Items.Insert(insertIndex++, data);
            if (!this.ButtonCanExecute)
            {
                this.ButtonCanExecute = true;
                this.Save.RaiseCanExecuteChanged();
            }
        }

        
    }
}